package com.dgut.lotterySystem.service.activityStatus.impl;

import com.dgut.lotterySystem.common.errorcode.ServiceErrorCodeConstants;
import com.dgut.lotterySystem.common.pojo.exception.ServiceException;
import com.dgut.lotterySystem.service.activityStatus.IActivityStatusManger;
import com.dgut.lotterySystem.service.activityStatus.operator.AbstractActivityOperator;
import com.dgut.lotterySystem.service.dto.ConvertActivityStatusDTO;
import com.dgut.lotterySystem.service.impl.ActivityServiceImpl;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

@Component
public class ActivityStatusMangerImpl implements IActivityStatusManger {

    public static final Logger logger= LoggerFactory.getLogger(ActivityStatusMangerImpl.class);
    @Autowired
    private final Map<String, AbstractActivityOperator> operatorMap=new HashMap<>();

    @Autowired
    private ActivityServiceImpl activityService;
    @Override
    @Transactional(rollbackFor = Exception.class)//保证事务的一致性，一旦抛出异常就回滚
    public void handleEvent(ConvertActivityStatusDTO convertActivityStatusDTO) {
        //活动状态扭转依赖奖品状态，扩展性差，可维护性差

        //map<String,AbstractActivityOperator>
        Map<String, AbstractActivityOperator> currMap=new HashMap<>(operatorMap);

        if(CollectionUtils.isEmpty(currMap)){
            logger.info("currMap 为空");
            return;
        }
        Boolean update=false;
        //先处理：奖品，人员
        update=processConventStatus(convertActivityStatusDTO,currMap,1);

        //后处理：活动
        update = processConventStatus(convertActivityStatusDTO,currMap,2) || update;


        if(update){
            //更新缓存
            activityService.cacheActivity(convertActivityStatusDTO.getActivityId());
        }

    }

    @Override
    public void rollBackHandleEvent(ConvertActivityStatusDTO convertActivityStatusDTO) {
        //需要回滚什么内容
        //奖品和人员肯定要回滚成Init，那么活动由于还有奖品抽完，所以状态肯定要回滚成Running

        Map<String, AbstractActivityOperator> currMap=new HashMap<>(operatorMap);
        for(AbstractActivityOperator operator:currMap.values()){
            operator.convert(convertActivityStatusDTO);
        }
        //缓存更新
        activityService.cacheActivity(convertActivityStatusDTO.getActivityId());
    }

    private Boolean processConventStatus(ConvertActivityStatusDTO convertActivityStatusDTO,
                                         Map<String, AbstractActivityOperator> currMap,
                                         int sequence) {
        Boolean update=false;
        //遍历currMap
        Iterator<Map.Entry<String, AbstractActivityOperator>> iterator=currMap.entrySet().iterator();
        while(iterator.hasNext()){
            AbstractActivityOperator operator=iterator.next().getValue();
            //operator是否需要转化
            if(!operator.sequence().equals(sequence)
                    ||!operator.needConvert(convertActivityStatusDTO)){
                continue;
            }
            //需要转化：转化
            if(!operator.convert(convertActivityStatusDTO)){
                logger.warn("{}转化状态失败",iterator.getClass().getName());
                throw new ServiceException(ServiceErrorCodeConstants.ACTIVITY_STATUS_CONVERT_ERROR);
            }
            //currMap删除当前的operator
            iterator.remove();
            update=true;
         }

        //返回
        return update;
    }
}
